home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / HRTIME.ASM < prev    next >
Assembly Source File  |  1991-12-16  |  5KB  |  221 lines

  1. ;
  2. ;    hrtime.asm -    Hi Resolution TIMEr for dos
  3. ;
  4.  
  5. ; Copyright notice begins here:
  6. ;    Copyright (c) 1991 by Thomas A. Roden
  7. ;    All Rights Reserved (with one exception).
  8. ;    The right to freely distribute this source and any executable code
  9. ;    it creates is granted, provided that this copyright notice is 
  10. ;    included in the source.
  11. ;
  12. ;    It is requested that the author's name (Thomas A. Roden) be included
  13. ;    in the acknowledgements of any product including this code, but this
  14. ;    request is in no way legally binding.
  15. ; Copyright notice ends here:
  16.  
  17.  
  18. IO_DELAY_NEEDED    equ    0    ; doesn't seem to need recovery time here
  19. PRVT_TICKS_USED    equ    1    ; if a private tick count is to be used
  20. IRET_IF_RESTORE    equ    0    ; if the interrupt flag is to be restored 
  21.                 ; with an IRET, or with the windows suggested
  22.                 ; method
  23.  
  24. ;
  25. ;    io_delay -    delay just a bit
  26. io_delay    macro
  27. if IO_DELAY_NEEDED
  28.     jmp    short $+2
  29. endif    ; IO_DELAY_NEEDED
  30. endm
  31.  
  32. PIC0_ADDR    equ    020h    ; I/O address of PIC 0
  33. TIMER0        equ    040h    ; I/O address of Timer 0 
  34. TIMER_STAT    equ    043h    ; I/O address for status/control of timers 0-2
  35.  
  36. PIC_RIRR    equ    00Ah    ; Read Interrupt Request Register of a PIC
  37. T0_R_S_C    equ    0C2h    ; Timer 0 Read Status and Count
  38.  
  39. DOS_GLOBALS    equ    040h    ; segment for 40:xx variables
  40. SYS_TIMER_CNT    equ    06Ch    ; offset for system count
  41.  
  42. .model    large
  43.  
  44. .code
  45.  
  46. assume    ds:nothing, es:nothing
  47.  
  48. if PRVT_TICKS_USED
  49. hrt_ticks    dd    0
  50. old_int8    dd    0
  51.  
  52. ;
  53. ;    hrt_isr -    the interrupt service routine for private tick 
  54. ;            counting for the hi-res timer
  55. ;
  56.     public    _hrt_isr
  57. _hrt_isr    proc    far
  58.  
  59.     add    word ptr cs:[hrt_ticks], 1
  60.     adc    word ptr cs:[hrt_ticks+2], 0
  61.  
  62.     jmp    dword ptr cs:[old_int8]
  63.  
  64. _hrt_isr    endp
  65. endif    ; PRVT_TICKS_USED
  66.  
  67. ;
  68. ;    hrt_open -    the init function for the hi-res timer
  69. ;
  70.     public    _hrt_open
  71. _hrt_open    proc    far
  72.  
  73.     push    ds        ; save this stuff to avoid bad crashes
  74.     push    es        ; save this stuff just to be paranoid
  75.     push    bx
  76.     push    cx
  77.     push    dx
  78.  
  79. if PRVT_TICKS_USED
  80.     xor    ax, ax
  81.     mov    word ptr cs:[hrt_ticks], ax
  82.     mov    word ptr cs:[hrt_ticks+2], ax
  83.  
  84.     mov    ax, 03508h    ; get int vector for int8 (irq0)
  85.     int    21h
  86.  
  87.     mov    word ptr cs:[old_int8], bx
  88.     mov    ax, es
  89.     mov    word ptr cs:[old_int8+2], ax
  90.  
  91.     mov    dx, seg _hrt_isr
  92.     mov    ds, dx
  93.     mov    dx, offset _hrt_isr
  94.     mov    ax, 02508h    ; set int vector for int8 (irq0)
  95.     int    21h
  96. endif    ; PRVT_TICKS_USED
  97.     pop    dx
  98.     pop    cx
  99.     pop    bx
  100.     pop    es
  101.     pop    ds
  102.  
  103.     xor    ax, ax
  104.  
  105.     ret
  106.  
  107. _hrt_open    endp
  108.  
  109. ;
  110. ;    hrt_close -    the un-init function for the hi-res timer
  111. ;
  112.     public    _hrt_close
  113. _hrt_close    proc    far
  114.  
  115.     push    ds        ; save this stuff to avoid bad crashes
  116.     push    es        ; save this stuff just to be paranoid
  117.     push    bx
  118.     push    cx
  119.     push    dx
  120. if PRVT_TICKS_USED
  121.     mov    dx, word ptr cs:[old_int8+2]
  122.     mov    ds, dx
  123.     mov    dx, word ptr cs:[old_int8]
  124.  
  125.     mov    ax, 02508h    ; set int vector for int8 (irq0)
  126.     int    21h
  127. endif    ; PRVT_TICKS_USED
  128.     pop    dx
  129.     pop    cx
  130.     pop    bx
  131.     pop    es
  132.     pop    ds
  133.  
  134.     xor    ax, ax
  135.  
  136.     ret
  137.  
  138. _hrt_close    endp
  139.  
  140. ;
  141. ;    hrtime -    the hi-res time reader
  142. ;
  143.     public    _hrtime
  144. _hrtime    proc    far
  145. if IRET_IF_RESTORE
  146.     pop    bx        ; return ip - to make iret return frame
  147.     pop    ax        ; return cs
  148.     pushf            ; flags
  149.     push    ax        ; cs
  150.     push    bx        ; ip
  151. else    ; IRET_IF_RESTORE
  152.     pushf            ; store flags on stack to check at end
  153. endif    ; IRET_IF_RESTORE
  154.  
  155.     cli                ; freeze ticker while checking
  156. hrt_readhw:
  157.     mov    al, T0_R_S_C        ; timer 0 read stat and count
  158.     out    TIMER_STAT, al
  159.     io_delay
  160.     in    al, TIMER0        ; store stat in ch
  161.     mov    ch, al
  162.     io_delay
  163.     in    al, TIMER0        ; store count in bx
  164.     mov    bl, al
  165.     io_delay
  166.     in    al, TIMER0
  167.     mov    bh, al
  168.  
  169.     io_delay            ; delay between timer and pic access
  170.  
  171.     mov    al, PIC_RIRR
  172.     out    PIC0_ADDR, al
  173.     io_delay
  174.     in    al, PIC0_ADDR
  175.  
  176.     test    al, 001h        ; check if system time is stale
  177.     jz    short hrt_timegood
  178.     mov    ax, 0ffffh        ; force max in lower part
  179.     jmp    short hrt_gotlo
  180. hrt_timegood:
  181.     test    ch, 040h
  182.     jnz    short hrt_readhw    ; timer invalid, retry
  183.  
  184.     mov    ax, bx            ; move count to more convenient reg
  185.     neg    ax            ; convert to count up
  186.     shl    ch, 1            ; bash ch to get high bit of status
  187.                     ; (output state) into high bit of 
  188.                     ; count via carry
  189.     cmc                ; invert carry to match count negation
  190.     rcr    ax, 1            ; mode 3 counts down twice by twos, 
  191.                     ; first with output high, then low
  192. hrt_gotlo:
  193. ;
  194. ;    This would be the place to shift ax down if less resolution
  195. ;    but greater range were needed.  The merging with system ticks
  196. ;    or parallel ticks would have to involve the same shifting.
  197. ;
  198. if PRVT_TICKS_USED    ; if a parallel tick count is to be used
  199.     mov    dx, word ptr cs:[hrt_ticks]
  200. else    ; PRVT_TICKS_USED
  201.     mov    dx, DOS_GLOBALS
  202.     mov    es, dx
  203.     mov    dx, es:[SYS_TIMER_CNT]    ; add system time
  204. endif    ; PRVT_TICKS_USED
  205.  
  206. if IRET_IF_RESTORE
  207.     iret
  208. else    ; IRET_IF_RESTORE
  209.     pop    bx            ; get flags down to restore interrupt flag
  210.     test    bx, 0200h        ; was IF set? (jump if no)
  211.     jz    short hrt_if_done
  212.     sti                ; restore interrupts to ON
  213. hrt_if_done:
  214.     ret
  215. endif    ; IRET_IF_RESTORE
  216.  
  217. _hrtime    endp
  218.  
  219.  
  220. end
  221.